package graphisme.Checkers;

import java.awt.GridLayout;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class CheckersGraphicalInterface extends JPanel {

	private static final long serialVersionUID = 6726708245444190460L;

	private static final int TAILLE = 9;

	private Case caseActive;
	private Case caseTmpActive;

	private boolean yourTurn = false;
	private String authorizedColor = "";
	private JFrame frame = new JFrame();
	private int nbBlanc=0;
	private int nbNoir=0;

	// communication part
	Socket socket = null;
	OutputStream out;
	BufferedWriter bufOut = null;

	public CheckersGraphicalInterface(int taille, Socket socket) {

		setLayout(new GridLayout(TAILLE, TAILLE));
		for (int i = 0; i < TAILLE; i++) {
			for (int j = 0; j < TAILLE; j++) {
				if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0)) {
					ajouterCase(Couleur.NOIR);
				} else {
					ajouterCase(Couleur.BLANC);
				}
			}
		}
		init();
	}

	private void ajouterCase(Couleur couleur) {
		Case case1 = new Case(couleur);
		case1.addMouseListener(new ListenerCase(case1, this));
		add(case1);
	}

	private Pion creerPion(Couleur couleur, boolean monte) {
		Pion pion = new Pion(couleur, monte);
		pion.addMouseListener(new ListenerPion(pion, this));
		return pion;
	}

	private void init() {
		for (int j = 0; j < TAILLE * 3; j += 2) {
			getCase(j).add(creerPion(Couleur.NOIR, false));
			getCase(TAILLE * TAILLE - j - 1)
					.add(creerPion(Couleur.BLANC, true));

		}
		setNbBlanc(14);
		setNbNoir(14);
	}

	public Case getCase(int i, int j) {
		return (Case) getComponent(j + i * TAILLE);
	}

	public Case getCase(int i) {
		return (Case) getComponent(i);
	}

	public void afficherPossibilites(Pion p) {
		int i = 0;
		int j = 0;
		for (int k = 0; k < TAILLE * TAILLE; k++) {
			getCase(k).setSelectionnee(false);
			if (getCase(k).getComponentCount() != 0
					&& getCase(k).getComponent(0).equals(p)) {
				caseActive = getCase(k);
				System.out.println("on set la case active"
						+ getLigne(caseActive) + "-" + getColonne(caseActive));
				setCaseTmpActive(getCase(k));
				i = k / TAILLE;
				j = k % TAILLE;

			}
		}
		selectionnerCases(i, j, p.getCouleur());
	}

	public void selectionnerCases(int i, int j, Couleur couleur) {
		Pion pion = (Pion) (getCase(i, j).getComponent(0));
		if (pion.isMonte()) {
			if (i - 1 >= 0 && j - 1 >= 0
					&& getCase(i - 1, j - 1).getComponentCount() == 0) {
				getCase(i - 1, j - 1).setSelectionnee(true);
			} else if (i - 2 >= 0
					&& j - 2 >= 0
					&& getCase(i - 2, j - 2).getComponentCount() == 0
					&& !((Pion) (getCase(i - 1, j - 1).getComponent(0)))
							.getCouleur().equals(couleur)) {
				getCase(i - 2, j - 2).setSelectionnee(true);
			}
			if (i - 1 >= 0 && j + 1 < TAILLE
					&& getCase(i - 1, j + 1).getComponentCount() == 0) {
				getCase(i - 1, j + 1).setSelectionnee(true);
			} else if (i - 2 >= 0
					&& j + 2 < TAILLE
					&& getCase(i - 2, j + 2).getComponentCount() == 0
					&& !((Pion) (getCase(i - 1, j + 1).getComponent(0)))
							.getCouleur().equals(couleur)) {
				getCase(i - 2, j + 2).setSelectionnee(true);
			}
		} else {
			if (i + 1 < TAILLE && j + 1 < TAILLE
					&& getCase(i + 1, j + 1).getComponentCount() == 0) {
				getCase(i + 1, j + 1).setSelectionnee(true);
			} else if (i + 2 < TAILLE
					&& j + 2 < TAILLE
					&& getCase(i + 2, j + 2).getComponentCount() == 0
					&& !((Pion) (getCase(i + 1, j + 1).getComponent(0)))
							.getCouleur().equals(couleur)) {
				getCase(i + 2, j + 2).setSelectionnee(true);
			}
			if (i + 1 < TAILLE && j - 1 >= 0
					&& getCase(i + 1, j - 1).getComponentCount() == 0) {
				getCase(i + 1, j - 1).setSelectionnee(true);
			} else if (i + 2 < TAILLE
					&& j - 2 >= 0
					&& getCase(i + 2, j - 2).getComponentCount() == 0
					&& !((Pion) (getCase(i + 1, j - 1).getComponent(0)))
							.getCouleur().equals(couleur)) {
				getCase(i + 2, j - 2).setSelectionnee(true);
			}

		}
	}

	public synchronized void play(Case case1) {
		if (caseActive != null && caseActive.getComponentCount() != 0) {
			case1.add(caseActive.getComponent(0));
			for (int k = 0; k < TAILLE * TAILLE; k++) {
				getCase(k).setSelectionnee(false);
			}
			if (Math.abs(getLigne(case1) - getLigne(caseActive)) == 2) {
				int i = (getLigne(case1) + getLigne(caseActive)) / 2;
				int j = (getColonne(case1) + getColonne(caseActive)) / 2;
				getCase(i, j).removeAll();
				getCase(i, j).validate();
				getCase(i, j).repaint();
			}
			caseActive.removeAll();
			caseActive.repaint();
			caseActive = null;
			case1.repaint();
			if (getLigne(case1) == 0) {
				Pion p = (Pion) (case1.getComponent(0));
				p.setMonte(false);
			}
			if (getLigne(case1) == TAILLE - 1) {
				Pion p = (Pion) (case1.getComponent(0));
				p.setMonte(true);
			}
		}

	}

	public int getLigne(Case case1) {
		int res = 0;
		for (int i = 0; i < TAILLE * TAILLE; i += 2) {
			if (getCase(i).equals(case1)) {
				res = i / TAILLE;
			}
		}
		return res;
	}

	public int getColonne(Case case1) {
		int res = 0;
		for (int i = 0; i < TAILLE * TAILLE; i += 2) {
			if (getCase(i).equals(case1)) {
				res = i % TAILLE;
			}
		}
		return res;
	}

	public String getAuthorizedColor() {
		return authorizedColor;
	}

	public void setAuthorizedColor(String authorizedColor) {
		this.authorizedColor = authorizedColor;
	}

	public boolean isYourTurn() {
		return yourTurn;
	}

	public void setYourTurn(boolean yourTurn) {
		this.yourTurn = yourTurn;
	}

	// send message to other player
	public void sendMsg(String msg) {
		try {
			this.bufOut.write(msg);
			this.bufOut.newLine();
			this.bufOut.flush();
		} catch (IOException e) {
			System.out
					.println("An error has been occured while sending the message to the server");
			e.printStackTrace();
		}
	}

	public Socket getSocket() {
		return socket;
	}

	public void setSocket(Socket socket) throws IOException {
		this.socket = socket;
		this.out = socket.getOutputStream();
		this.bufOut = new BufferedWriter(new OutputStreamWriter(out));
	}

	public OutputStream getOut() {
		return out;
	}

	public void setOut(OutputStream out) {
		this.out = out;
	}

	public BufferedWriter getBufOut() {
		return bufOut;
	}

	public void setBufOut(BufferedWriter bufOut) {
		this.bufOut = bufOut;
	}

	public Case getCaseActive() {
		return caseActive;
	}

	public void setCaseActive(Case ca) {
		this.caseActive = ca;
	}

	public Case getCaseTmpActive() {
		return caseTmpActive;
	}

	public void setCaseTmpActive(Case caseTmpActive) {
		this.caseTmpActive = caseTmpActive;
	}

	public JFrame getFrame() {
		return frame;
	}

	public void createMSgBOX(String sentence) {
		this.frame = new JFrame();
		JOptionPane.showMessageDialog(

		frame, sentence, "Information", JOptionPane.PLAIN_MESSAGE);
	}

	public void clearFrame() {
		this.frame.invalidate();
		this.frame.dispose();
		this.frame.removeAll();
	}

	public int getNbBlanc() {
		return nbBlanc;
	}

	public void setNbBlanc(int nbBlanc) {
		this.nbBlanc = nbBlanc;
	}

	public int getNbNoir() {
		return nbNoir;
	}

	public void setNbNoir(int nbNoir) {
		this.nbNoir = nbNoir;
	}
	
	// method calculating the remaining pawns on the board
	public void calculNbPionleft() {
		int tptBlack = 0;
		int tptWhite = 0;
		
		for (int i = 0; i < TAILLE; i++) {
			for (int j = 0; j < TAILLE; j++) {
				System.out.println(getCase(i, j).getComponentCount());
				// if there is a pawn on the selected box
				if (getCase(i, j).getComponentCount()!=0) {
					// if it is a black pawn
					if ((((Pion) getCase(i, j).getComponent(0)).getCouleur().toString())
							.equals("NOIR")) {
						// increment the number of black pawn
						tptBlack += 1;
					}// else increment the number of white pawn
					else if ((((Pion) getCase(i, j).getComponent(0))
							.getCouleur().toString()).equals("BLANC")) {
						tptWhite += 1;
					}
				}
			}
		}
		// set number of remaining pawns
		this.nbBlanc = tptWhite;
		this.nbNoir = tptBlack;
		//log syso
		System.out.println("Number of black pawns remaining" + nbNoir);
		System.out.println("Number of white pawns remaining" + nbBlanc);
	}
}
